import { defineStore } from 'pinia'
import { useUserStore } from './user'
import { menuApi } from '@/api/menu'
import { constantRoutes } from '@/router/routes'
import type { MenuItem } from '@/types/api'
import type { AppRouteRecordRaw } from '@/types/system'
import router from '@/router'

// 预加载所有视图组件，解决 Vite 对多级动态导入的限制
// 键通常为以 /src 开头的绝对路径
const viewModules: Record<string, any> = import.meta.glob('@/views/**/*.vue')

interface PermissionState {
    routes: AppRouteRecordRaw[]
    addRoutes: AppRouteRecordRaw[]
    menus: MenuItem[]
    // ❌ 删除：permissions 字段（与 userStore.permissions 重复，使用 userStore 作为权威来源）
    menuLoaded: boolean
    loadingMenus: boolean
    permVersion?: number  // ✅ 权限版本号，用于缓存失效判断
    routesMounted: boolean  // ✅ 标记路由是否已挂载到 router
}

export const usePermissionStore = defineStore('permission', {
    state: (): PermissionState => ({
        routes: [],
        addRoutes: [],
        menus: [],
        menuLoaded: false,
        loadingMenus: false,
        permVersion: undefined,  // ✅ 初始化权限版本号
        routesMounted: false  // ✅ 初始化路由挂载标志
    }),

    getters: {
        // 获取所有路由
        allRoutes: (state): AppRouteRecordRaw[] => {
            return [...constantRoutes, ...state.addRoutes]
        },

        // 获取侧边栏菜单（临时取消过滤以便定位问题）
        sidebarMenus: (state): MenuItem[] => {
            return (state.menus as any[]) as unknown as MenuItem[]
        },

        // 获取面包屑导航
        breadcrumbRoutes: (state): AppRouteRecordRaw[] => {
            return state.routes.filter(route =>
                route.meta?.breadcrumb !== false
            )
        }
    },

    actions: {
        // 将生成的路由挂载到 Router。确保父子关系正确，并避免重复注册：
        // - 顶层作为根路由添加
        // - 子路由通过 addRoute(parentName, child) 添加
        // - 路由名称或同路径存在则跳过
        mountRoutesToRouter(asyncRoutes: AppRouteRecordRaw[]) {
            const addRecursively = (route: AppRouteRecordRaw, parentName?: string, parentPath?: string) => {
                const r: any = route as any
                // if (import.meta.env.MODE !== 'production') {
                //     console.log('[Permission] addRoute', {
                //         parentName: parentName || null,
                //         name: route.name,
                //         path: route.path
                //     })
                // }
                const routerAny = router as any
                const hasByName = r.name && routerAny.hasRoute?.(r.name)
                // 仅在当前父级路径下做路径重复判断，避免不同父级的同名相对子路径被误判
                const pathExists = (() => {
                    if (parentName) {
                        const parent = routerAny.hasRoute?.(parentName) ? routerAny.getRoutes?.().find((rt: any) => rt.name === parentName) : null
                        const base = parent?.path || ''
                        const target = typeof r.path === 'string' ? (r.path.startsWith('/') ? r.path : (base.endsWith('/') ? base + r.path : base + '/' + r.path)) : ''
                        const all = routerAny.getRoutes?.() || []
                        return !!target && all.some((rt: any) => rt.path === target)
                    }
                    const all = routerAny.getRoutes?.() || []
                    return typeof r.path === 'string' && all.some((rt: any) => rt.path === r.path)
                })()

                if (!parentName) {
                    // 根路由：若已存在则跳过
                    if (!hasByName && !pathExists) {
                        routerAny.addRoute(r)
                    }
                } else {
                    const hasParent = (router as any).hasRoute?.(parentName)
                    if (hasParent) {
                        // 绝对子路径：尝试找到其顶层父（如 /system/* → parentName=system）并转为相对路径添加
                        if (typeof r.path === 'string' && r.path.startsWith('/')) {
                            const all = (router as any).getRoutes?.() || []
                            const topSeg = '/' + r.path.replace(/^\/+/, '').split('/')[0]
                            // 尝试匹配现有根路由（如 /system、/monitor 等）
                            const parentRoute = all.find((rt: any) => rt.path === topSeg)
                            if (parentRoute && parentRoute.name) {
                                const rel = r.path.replace(new RegExp('^' + topSeg.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + '/?'), '')
                                const child = { ...r, path: rel }
                                const childExists = child.name && routerAny.hasRoute?.(child.name)
                                if (!childExists) {
                                    routerAny.addRoute(parentRoute.name, child)
                                }
                            } else {
                                if (!hasByName && !pathExists) {
                                    routerAny.addRoute(r)
                                }
                            }
                        } else {
                            const childExists = r.name && routerAny.hasRoute?.(r.name)
                            if (!childExists) {
                                routerAny.addRoute(parentName, r)
                            }
                        }
                    } else {
                        // 兜底：父路由不存在，则将子路由提升为根级，并补全绝对路径
                        const childPath = typeof r.path === 'string' ? r.path : ''
                        const abs = parentPath ? `/${String(parentPath).replace(/^\//,'')}/${childPath}`.replace(/\/+/g, '/') : `/${childPath}`.replace(/\/+/g, '/')
                        r.path = abs
                        if (!hasByName && !pathExists) {
                            routerAny.addRoute(r)
                        }
                    }
                }
                // 开发日志降噪：移除每次 add 后的状态打印
                if (Array.isArray(route.children) && route.children.length > 0) {
                    const currentName = route.name as string | undefined
                    const currentPath = route.path as string | undefined
                    route.children.forEach(child => addRecursively(child, currentName, currentPath))
                }
            }
            asyncRoutes.forEach(r => addRecursively(r))
        },
        // 生成路由
        async generateRoutes(): Promise<AppRouteRecordRaw[]> {
            const userStore = useUserStore()

            // ✅ 优化：版本号一致且已加载菜单，使用缓存
            if (this.menuLoaded && this.menus.length > 0 && this.permVersion === userStore.permVersion) {
                console.log('✅ 使用缓存的菜单数据，跳过API请求 (版本号一致)')

                // ✅ 修复：页面刷新后 addRoutes 为空（因为不能序列化），需要从 menus 重新生成
                if (this.addRoutes.length === 0) {
                    console.log('🔧 从缓存的菜单数据重新生成路由...')
                    const asyncRoutes = this.generateAsyncRoutes(this.menus as any)
                    this.addRoutes = asyncRoutes
                    this.routes = [...constantRoutes, ...asyncRoutes]
                }

                // ✅ 检查路由是否已挂载到 router，如果没有则重新挂载
                const routerAny = router as any
                const needsRemount = this.addRoutes.length > 0 &&
                    this.addRoutes[0].name &&
                    !routerAny.hasRoute?.(this.addRoutes[0].name)

                if (needsRemount) {
                    console.log('🔧 检测到路由未挂载（页面刷新后），重新挂载到 router...')
                    this.mountRoutesToRouter(this.addRoutes)
                }
                
                // ✅ 统一设置状态标志（确保与非缓存分支一致）
                this.routesMounted = true
                this.menuLoaded = true
                this.loadingMenus = false
                this.permVersion = userStore.permVersion  // ✅ 确保版本号同步

                return this.routes.length ? this.routes : [...constantRoutes, ...this.addRoutes]
            }

            // 并发保护
            if (this.loadingMenus) {
                return this.routes.length ? this.routes : constantRoutes
            }

            console.log('🔄 从后端获取菜单数据... (版本号变化或首次加载)')
            this.loadingMenus = true

            try {
                // ✅ 优化：权限已在 login/refreshToken 时通过 authInfo 获取，无需重复调用API
                // 如果 userStore.permissions 为空，才从API获取（兜底逻辑）
                if (userStore.permissions.size === 0) {
                try {
                    const { authApi } = await import('@/api/auth')
                    const permsResp = await authApi.getCurrentUserPermissions()
                    const perms = Array.isArray(permsResp.data) ? permsResp.data : []
                    if (perms.length) {
                        userStore.setPermissions(perms)
                    }
                } catch (e) {
                        console.warn('[Permission] 获取权限失败:', e)
                    }
                }

                // ✅ 优化：直接使用登录时返回的树形菜单（避免额外API调用）
                const menuData = (userStore.menus || []) as MenuItem[]
                console.log(`📜 使用登录返回的树形菜单: ${menuData.length}个根菜单`)

                // ✅ 优化：权限数据的权威来源是后端authInfo，不再从菜单提取并合并
                // 仅在调试模式下记录菜单中包含的权限信息
                if (import.meta.env.MODE !== 'production') {
                    const menuPermissions = this.extractPermissions(menuData as unknown as MenuItem[])
                    console.log('[Permission] 菜单中的权限数量:', menuPermissions.length)
                }

                // 1️⃣ 保存菜单数据
                this.menus = menuData as unknown as MenuItem[]
                console.log('💾 菜单已保存到 permissionStore.menus:', this.menus.length, this.menus.map(m => ({ id: m.id, name: m.name, title: m.title })))

                // 2️⃣ 根据菜单生成动态路由
                const asyncRoutes = this.generateAsyncRoutes(menuData)
                if (import.meta.env.MODE !== 'production') {
                    console.log('[Permission] asyncRoutes length:', asyncRoutes.length)
                    if (asyncRoutes.length) {
                        console.log('[Permission] first async route:', { name: asyncRoutes[0].name, path: asyncRoutes[0].path, children: asyncRoutes[0].children?.map(c => ({ name: c.name, path: c.path })) })
                    }
                }

                // 3️⃣ 存储路由
                this.addRoutes = asyncRoutes
                this.routes = [...constantRoutes, ...asyncRoutes]
                
                // 4️⃣ 挂载动态路由到 router
                this.mountRoutesToRouter(asyncRoutes)
                if (import.meta.env.MODE !== 'production') {
                    const all = (router as any).getRoutes?.() || []
                    console.log('[Permission] router.getRoutes count:', all.length)
                    console.log('[Permission] has /system?', all.some((r: any) => r.path === '/system'))
                    console.log('[Permission] has /system/user?', all.some((r: any) => r.path === '/system/user'))
                }

                // 5️⃣ 标记所有操作完成
                this.routesMounted = true
                this.menuLoaded = true  // ✅ 所有操作完成后才设置，确保 Sidebar 可以安全渲染
                this.loadingMenus = false
                this.permVersion = userStore.permVersion
                
                console.log('✅ generateRoutes 完成: menuLoaded=true, routesMounted=true')

                return this.routes
            } catch (error) {
                console.error('生成路由失败:', error)
                console.warn('Menu API failed, using fallback menus for SUPER_ADMIN')

                // 如果API失败，为SUPER_ADMIN创建默认菜单
                const userStore = useUserStore()
                if (userStore.isSuperAdmin) {
                    const defaultMenus: MenuItem[] = [
                        {
                            id: 'menu_system',
                            name: 'system',
                            title: '系统管理',
                            path: '/system',
                            icon: 'Setting',
                            menuType: 'DIR',
                            visible: true,
                            orderNo: 10,
                            children: [
                                {
                                    id: 'menu_system_user',
                                    name: 'system_user',
                                    title: '用户管理',
                                    path: '/system/user',
                                    component: 'system/user/index',
                                    icon: 'User',
                                    menuType: 'MENU',
                                    visible: true,
                                    orderNo: 11,
                                    permission: 'system:user:list'
                                }
                            ]
                        }
                    ]
                    this.menus = defaultMenus
                    const asyncRoutes = this.generateAsyncRoutes(defaultMenus)
                    this.addRoutes = asyncRoutes
                    this.routes = [...constantRoutes, ...asyncRoutes]
                    this.mountRoutesToRouter(asyncRoutes)
                    // ✅ 所有操作完成后才设置标记
                    this.routesMounted = true
                    this.menuLoaded = true
                    this.loadingMenus = false
                    this.permVersion = userStore.permVersion
                    return this.routes
                }
                
                throw error
            } finally {
                this.loadingMenus = false
            }
        },

        resetRoutes() {
            this.menus = []
            this.addRoutes = []
            this.routes = [...constantRoutes]
            this.menuLoaded = false
            this.permVersion = undefined
            this.routesMounted = false
            

            // 递归收集所有静态路由的 name，用 Set 存储以提高查找效率
            const constantRouteNames = new Set<string>()
            const collectNames = (routes: AppRouteRecordRaw[]) => {
                routes.forEach(route => {
                    if (route.name) {
                        constantRouteNames.add(route.name as string)
                    }
                    if (route.children) {
                        collectNames(route.children)  // 递归处理子路由
                    }
                })
            }
            collectNames(constantRoutes)  // 执行一次：O(n)，n 为静态路由总数
            
            // 从路由器移除动态路由（保留静态路由）
            // router.getRoutes() 返回扁平数组，包含所有已注册的路由
            const allRoutes = router.getRoutes()
            allRoutes.forEach(route => {
                // 使用 Set.has() 判断：O(1) 时间复杂度
                if (route.name && !constantRouteNames.has(route.name as string)) {
                    router.removeRoute(route.name)
                }
            })
        },

        setMenus(menus: MenuItem[]) {
            this.menus = menus
        },

        setRoutes(routes: AppRouteRecordRaw[]) {
            this.addRoutes = routes
            this.routes = [...constantRoutes, ...routes]
        },

        // 根据菜单数据生成路由
        generateAsyncRoutes(menus: MenuItem[]): AppRouteRecordRaw[] {
            const build = (node: MenuItem, parentPath?: string): AppRouteRecordRaw | null => {
                const route = this.createRoute(node, parentPath || '')
                if (!route) return null
                if (node.children?.length) {
                    route.children = node.children
                        .map(child => build(child, route.path))
                        .filter((r): r is AppRouteRecordRaw => r !== null)
                }
                return route
            }
            return menus.map(m => build(m)).filter((r): r is AppRouteRecordRaw => r !== null)
        },

        // 创建单个路由 - 只支持新系统标准
        createRoute(menu: MenuItem, parentPath: string): AppRouteRecordRaw | null {
            // 只支持新系统: DIR-目录, MENU-菜单, BUTTON-按钮
            if (menu.menuType !== 'DIR' && menu.menuType !== 'MENU') {
                return null
            }

            const path = parentPath ? menu.path : menu.path.startsWith('/') ? menu.path : `/${menu.path}`
            const component = menu.menuType === 'DIR' && !parentPath ? this.loadComponent('Layout') : 
                            menu.menuType === 'MENU' ? this.loadComponent(menu.component) : undefined

            const route: AppRouteRecordRaw = {
                path,
                name: menu.name,
                meta: {
                    title: menu.title,
                    icon: menu.icon,
                    keepAlive: menu.isCache || false,
                    hidden: !menu.visible,
                    roles: [],
                    permissions: menu.permission ? [menu.permission] : [],
                    breadcrumb: true,
                    affix: false
                }
            }

            if (component) route.component = component

            // 外链处理
            if (menu.path && (menu.path.startsWith('http://') || menu.path.startsWith('https://'))) {
                ;(route.meta as any).externalLink = menu.path
            }

            return route
        },

        // 动态加载组件
        loadComponent(componentPath: string | undefined): any {
            if (!componentPath) return () => import('@/views/error/404.vue')
            if (componentPath === 'Layout') return () => import('@/layouts/Layout.vue')
            if (componentPath === 'IFrame') return () => import('@/components/IFrame/index.vue')

            const normalize = (p: string) => p.startsWith('/') ? p.slice(1) : 
                                           p.endsWith('.vue') ? p.slice(0, -4) : 
                                           p.startsWith('views/') ? p.slice(6) : p

            const normalized = normalize(componentPath)
            const candidates = [
                `/src/views/${normalized}.vue`,
                `/src/views/${normalized}/index.vue`
            ]

            for (const key of Object.keys(viewModules)) {
                for (const candidate of candidates) {
                    if (key === candidate) {
                        return viewModules[key]
                    }
                }
            }

            return () => import('@/views/error/404.vue')
        },

        // 提取权限（调试用）
        extractPermissions(menus: MenuItem[]): string[] {
            const perms: Set<string> = new Set()
            const walk = (nodes: MenuItem[]) => {
                nodes.forEach(m => {
                    if (m.permission) perms.add(m.permission)
                    if (m.children?.length) walk(m.children)
                })
            }
            walk(menus)
            return Array.from(perms)
        },

        // 按权限过滤菜单
        filterMenusByPermission(menus: MenuItem[], userPermissions: Set<string>): MenuItem[] {
            return menus.filter(m => {
                if (!m.permission || userPermissions.has(m.permission)) {
                    if (m.children?.length) {
                        m.children = this.filterMenusByPermission(m.children, userPermissions)
                    }
                    return true
                }
                return false
            })
        }
    },

    // 持久化配置
    persist: {
        key: 'kexio-permission-store',
        // ✅ 统一使用 localStorage，通过启动时检查和登出时清除来实现"记住我"功能
        storage: localStorage,
        // ✅ 持久化 menus、menuLoaded、permVersion 以支持智能缓存
        // ⚠️ routesMounted 不持久化，页面刷新后需要重新挂载路由
        // ❌ permissions 不持久化（已删除，统一使用 userStore.permissions）
        paths: ['menus', 'menuLoaded', 'permVersion']
    }
})

